<?php

/*
 * Import constants to the Database
 *
 *
 * @uses classes/babel/BabelZipArchive.php
 * @uses classes/babel/BabelLanguageFile.php
 * @uses classes/babel/BabelDBLanguageFile.php
 * @uses classes/babel/BabelConstant.php
 * @package BABEL
 * @since   BABEL 0.1.0
 * @version $Id: upload.php 766 2008-05-14 08:52:59Z bjori $
 * @copyright Copyright (C) 2008 Team Babel
 * @author  Hannes Magnussson
 * @license LGPL
 */


require $ROOT_DIR . "classes/babel/BabelZipArchive.php";
require $ROOT_DIR . "classes/babel/BabelLanguageFile.php";
require $ROOT_DIR . "classes/babel/BabelDBLanguageFile.php";
require $ROOT_DIR . "classes/babel/BabelConstant.php";

if($_SERVER["REQUEST_METHOD"] !== "POST") {
	include "includes/babel/prepend.php";
	throw new Exception("Unknown method");
}

/* {{{ Uploading progress bar */
$uploaddir = BABEL_UPLOAD_DIRECTORY;
if (isset($_POST["APC_UPLOAD_PROGRESS"])) {
	$status = apc_fetch("upload_" . $_POST['APC_UPLOAD_PROGRESS']);
	$uploadfile = $uploaddir . basename($_FILES["up"]["name"]);

	if (move_uploaded_file($_FILES["up"]["tmp_name"], $uploadfile)) {
		$_SESSION[$_POST['APC_UPLOAD_PROGRESS']] = $uploadfile;
		$status["done"] = 1;
	} else {
		$status["done"] = 0;
	}
	echo json_encode($status);
	exit;
}
/* }}} */

include "includes/babel/prepend_no_gui.php";
/* {{{ Quick'n'dirty tpl helper */
function tpl(array $array = null, $return = false) {
	global $obj_tpl;

	static $count = 1;
	static $map = array(
		"ROW_TR_BGCOLOR"        => "color",
		"VAR_ROWNUMBER"         => "row",
		"VAR_FILENAME"          => "fn",
		"VAR_CONSTANT_INSERTED" => "new",
		"VAR_CONSTANT_UPDATED"  => "up",
		"VAR_CONSTANT_SKIPPED"  => "old",
		"VAR_CONSTANT_STATUS"   => "status",
	);
	static $stats = array(
		"new" => 0,
		"up"  => 0,
		"old" => 0,
	);

	if ($return) {
		return $stats;
	}

	$bind = array(
		"ROW_TR_BGCOLOR" => ($count % 2 ? '#EEEEEE' : '#DDDDDD'),
		"VAR_FILENAME"   => "Unknown",
		"VAR_ROWNUMBER"  => $count++,
		"VAR_CONSTANT_INSERTED" => 0,
		"VAR_CONSTANT_UPDATED"  => 0,
		"VAR_CONSTANT_SKIPPED"  => 0,
		"VAR_CONSTANT_STATUS"   => "OK",
	);
	foreach($map as $tpl => $key) {
		if (isset($array[$key])) {
			$bind[$tpl] = $array[$key];
		}
	}
	$stats["new"] += $bind["VAR_CONSTANT_INSERTED"];
	$stats["up"]  += $bind["VAR_CONSTANT_UPDATED"];
	$stats["old"] += $bind["VAR_CONSTANT_SKIPPED"];

	$obj_tpl->setVar($bind);
	$obj_tpl->parse("filelist_ref", "filelist", true);
}
/* }}} */

if (!isset($_GET["filename"])) {
	throw new Exception("Unknown filename: " . $_GET["filename"]);
}

// Fetch the actual file location from the session
$upfile = $_SESSION[$_GET["filename"]];
try {
	$zip = new BabelZipArchive($upfile);
} catch(Exception $e) {
	// If this wasn't a zip archive then lets try a plain XML file
	$file = BabelLanguageFile::createFile(fopen($upfile, "r+"));
	$zip = array($file);
}


$obj_tpl->setFile("import", "babel/import.html");
$obj_tpl->setBlock("import", "filelist", "filelist_ref");

// Loop over the zip archive || array of file
foreach($zip as $xmlfile) {
	// Import the XML file
	importXMLLangFile($xmlfile);
}
function importXMLLangFile(BabelLanguageFile $xmlfile) {
	// We only want to prepare the query once
	static $stmt = null;
	if ($stmt === null) {
		$stmt = PDODB::connect()->prepare("SELECT revision, file_id AS id FROM babel_files WHERE name = ?");
	}
	
	if (!$stmt->execute(array((string)$xmlfile))) {
		throw new Exception("Query failed");
	}

	if ($stmt->rowCount() == 0) {
		// New file
		$dbfile = new BabelDBLanguageFile((string)$xmlfile);
		$dbfile->insertFilename($xmlfile->getRevision());
	} else {
		// Fetch the revision and id stored in the DB
		$dbdata = $stmt->fetch(PDO::FETCH_ASSOC);

		// Skip the file if it isn't newer than the one in the database
		if (!($xmlfile->getRevision() > $dbdata["revision"])) {
			tpl(array(
				"fn"     => (string)$xmlfile,
				"status" => "Skipped",
			));
			/* We already have the latest revision of the file, skip it */
			continue;
		}
		$dbfile = new BabelDBLanguageFile((string)$xmlfile, $xmlfile->getMeta()+array("id" => $dbdata["id"]));
	}

	$modCount = $newCount = $oldCount = 0;
	foreach($xmlfile as $constant) {
		if ($constant instanceof BabelLanguageFile) {
			// Support for nested files
			importXMLLangFile($constant);
			continue;
		}

		// Pre-fetch all the constants
		$dbfile->getConstants();

		switch ($dbfile->hasConstant($constant)) {
		case BabelDBLanguageFile::NOT_MODIFIED:
			++$oldCount;
			break;

		case BabelDBLanguageFile::NOT_FOUND:
			++$newCount;
			$dbfile->insertConstant($constant);
			break;

		case BabelDBLanguageFile::FOUND:
			++$modCount;
			$dbfile->updateConstant($constant);
			break;
		}
	}
	tpl(array(
		"fn"     => (string)$xmlfile,
		"new"    => $newCount,
		"up"     => $modCount,
		"old"    => $oldCount,
		"status" => "OK",
	));

	// Done updating
	// Update the file timestamp
	$dbfile->updateRevision($xmlfile->getRevision());
}
$stats = tpl(null, true);
$obj_tpl->setVar(array(
	"VAR_TOTAL_CONSTANTS"          => array_sum($stats),
	"VAR_TOTAL_CONSTANTS_INSERTED" => $stats["new"],
	"VAR_TOTAL_CONSTANTS_UPDATED"  => $stats["up"],
	"VAR_TOTAL_CONSTANTS_SKIPPED"  => $stats["old"],
	"VAR_TOTAL_LANGUAGES"          => count(BabelDBLanguageFile::getAllLangs()),
	"VAR_TOTAL_NEW_CONSTANTS"      => $stats["new"],
));

$retval =  $obj_tpl->parse("import", "import");
$obj_tpl->p("import");
// Remove the uploaded file
unlink($upfile);

